/* Copyright (c) 2009 the author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.grails.plugins.wave.*
import com.google.wave.api.*
import com.google.wave.api.impl.*
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH

/**
 * MyRobotService
 *
 * Robot Demo Implementation
 *
 * @author david.trattnig
 */
class GroovyBotRobotService implements GrailsWaveRobot {

	final String GROOVY_TAG = "@@groovy"
	
    static robotName = "Groovy:Bot"
	static robotVersion = "8"
	static robotCapabilities = [EventType.WAVELET_BLIP_CREATED,
								EventType.WAVELET_SELF_ADDED,
								EventType.BLIP_SUBMITTED]
	static imageUrl = "http://${CH.config.google.appengine.application}.appspot.com/images/robot.jpg"
	static profileUrl = "http://${CH.config.google.appengine.application}.appspot.com"
	
	/** create the robot behaviour here **/
    public void processEvents(RobotMessageBundle bundle) {
		
		for (e in bundle.events) {
			switch (e.type) {
				case EventType.BLIP_SUBMITTED: 
					blipSubmitted(bundle, e) 
					break
  				case EventType.WAVELET_BLIP_CREATED: 
					waveletBlipCreated(bundle, e)
					break
				case EventType.WAVELET_SELF_ADDED: 
					waveletSelfAdded(bundle, e)
					break
			}
		}	
    }

	private void waveletSelfAdded(RobotMessageBundle bundle, Event event) {
		
        def root = bundle.wavelet.rootBlip
        
		root.document.append "Welcome to the Grails Plugin Sample Bot!\n\n"
		root.document.append "This bot evaluates groovy scripts in Google Wave.\n"
		root.document.append "Simply tag your code with @@groovy to be compiled.\n"
		root.document.append "Updated blips won't be recompiled and note that\n"
		root.document.append "only the script's return value is displayed:\n"
		root.document.append "e.g. @@groovy return \"hello world\"\n"
		root.document.append "-------------------------------------------------------"	
		//root.document.append "[ <<gadget here>> ]"	
		
		def blip = root.createChild()
		blip.document.append("how may I serve?")	
	}
	
	private void blipSubmitted(RobotMessageBundle bundle, Event event) {
		
        def textView = event.blip.document as TextView

		if (textView.text.contains(GROOVY_TAG))
			processGroovyScript(event)
		else if (textView.text =~ /version|old|age/) 
			replyRobotVersion(event)
	}
	
	private void processGroovyScript(Event event) {
		
		def res=null, shell=new GroovyShell()
		def textView = event.blip.document as TextView
		def source = textView.text.replace(GROOVY_TAG,"")
		log.info "source: $source"
		
		try {
			res = shell.evaluate(source)
		} catch (Exception e) {
			res = e.toString()
		} finally {
			log.info "shell response: $res"
		}
		
		def outBlip = event.blip.createChild()
		outBlip.document.append "GROOVY SHELL OUT >>\n\n$res"
	}
	
	private void replyRobotVersion(Event event) {

		def b = event.blip.createChild()
		b.document.append "my version is ${this.robotVersion}"
	}	

}
